from PySide6.QtWidgets import QWidget, QVBoxLayout, QTreeView, QSizePolicy, QLabel, QTreeWidget, QTreeWidgetItem, QMenu, QInputDialog, QDialog, QHBoxLayout, QPushButton, QLineEdit
from PySide6.QtCore import Qt, QSize
from PySide6.QtGui import QIcon
from utility.template_edit_dialog import TemplateEditDialog
from theme.manager import ThemeManager
import os
from utility.template_generate_dialog import TemplateGenerateDialog

class TemplateManagerTab(QWidget):
    def __init__(self, parent=None):
        super().__init__(parent)
        self.template_dir = os.path.expanduser('~/.a-terminal/templates')
        self.theme_manager = ThemeManager()
        self.setup_ui()
        self.setup_icons()
        self.init_root_node()
        self.load_templates()
        self.setup_context_menu()

    def setup_ui(self):
        """初始化UI"""
        layout = QVBoxLayout(self)
        layout.setContentsMargins(0, 0, 0, 0)
        layout.setSpacing(0)

        # 设置尺寸策略，使组件能够适应QTabWidget的宽度
        self.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)

        # 添加搜索框
        search_layout = QHBoxLayout()
        search_layout.setContentsMargins(0, 8, 0, 8)
        search_layout.setSpacing(8)
        self.search_box = QLineEdit()
        self.search_box.setPlaceholderText("搜索模板...")
        self.search_box.setObjectName("search_box")
        self.search_box.textChanged.connect(self.filter_templates)
        search_layout.addWidget(self.search_box)
        layout.addLayout(search_layout)

        # 创建树形控件
        self.tree = QTreeWidget()
        self.tree.setObjectName('template_tree')
        self.tree.setHeaderHidden(True)  # 隐藏表头
        self.tree.setColumnCount(1)  # 设置列数为1
        self.tree.setDragEnabled(True)  # 启用拖拽
        self.tree.setAcceptDrops(True)  # 接受拖放
        self.tree.setDropIndicatorShown(True)  # 显示拖放指示器
        self.tree.dropEvent = self.handleDropEvent  # 自定义拖放事件处理
        self.tree.setSelectionMode(QTreeWidget.SelectionMode.SingleSelection)  # 单选模式
        self.tree.setIconSize(QSize(16, 16))  # 设置图标大小
        
        # 设置树形控件的尺寸策略，使其能够正确扩展填充可用空间
        self.tree.setSizePolicy(QSizePolicy.Policy.Expanding, QSizePolicy.Policy.Expanding)
        
        layout.addWidget(self.tree)

    def setup_icons(self):
        """设置图标资源"""
        # 获取当前主题
        current_theme = self.theme_manager.get_current_theme()
        theme_suffix = "light" if "light" in current_theme.lower() else "dark"
        
        # 获取图标文件的绝对路径
        icons_dir = os.path.join(os.path.dirname(os.path.dirname(__file__)), 'static', 'icons')
        folder_icon_path = os.path.join(icons_dir, f'folder-{theme_suffix}.png')
        template_icon_path = os.path.join(icons_dir, f'model-{theme_suffix}.png')
        
        # 创建图标
        self.folder_icon = QIcon(folder_icon_path)
        self.template_icon = QIcon(template_icon_path)

    def init_root_node(self):
        """初始化根节点"""
        self.root = QTreeWidgetItem(self.tree)
        self.root.setText(0, '所有模板')
        self.root.setIcon(0, self.folder_icon)
        self.root.setExpanded(True)

    def load_templates(self):
        """加载模板列表"""
        # 确保模板目录存在
        if not os.path.exists(self.template_dir):
            os.makedirs(self.template_dir)

        # 清空现有项
        self.root.takeChildren()

        # 递归加载模板文件和目录
        self._load_templates_recursive(self.template_dir, self.root)
    
    def _load_templates_recursive(self, directory, parent_item):
        """递归加载目录中的模板和子目录"""
        # 获取目录中的所有项目
        items = os.listdir(directory)
        
        # 先处理子目录
        for item in sorted(items):
            item_path = os.path.join(directory, item)
            if os.path.isdir(item_path):
                # 创建目录节点
                dir_item = QTreeWidgetItem(parent_item)
                dir_item.setText(0, item)
                dir_item.setIcon(0, self.folder_icon)
                # 设置目录数据
                dir_data = {
                    'type': 'directory',
                    'name': item,
                    'path': item_path
                }
                dir_item.setData(0, Qt.ItemDataRole.UserRole, dir_data)
                # 递归加载子目录
                self._load_templates_recursive(item_path, dir_item)
        
        # 再处理模板文件
        for item in sorted(items):
            if item.endswith('.txt'):
                template_item = QTreeWidgetItem(parent_item)
                template_item.setText(0, item[:-4])  # 去掉.txt后缀
                template_item.setIcon(0, self.template_icon)
                # 设置模板数据
                template_data = {
                    'type': 'template',
                    'name': item[:-4],
                    'path': os.path.join(directory, item)
                }
                template_item.setData(0, Qt.ItemDataRole.UserRole, template_data)

    def setup_context_menu(self):
        """设置右键菜单"""
        self.tree.setContextMenuPolicy(Qt.ContextMenuPolicy.CustomContextMenu)
        self.tree.customContextMenuRequested.connect(self.show_context_menu)

    def show_context_menu(self, position):
        """显示右键菜单"""
        item = self.tree.itemAt(position)
        if not item:
            return

        menu = QMenu()
        
        # 获取项目数据
        item_data = item.data(0, Qt.ItemDataRole.UserRole)
        item_type = item_data.get('type') if item_data else None
        
        # 根据项目类型显示不同的菜单
        if item == self.root:
            # 根节点菜单
            add_template_action = menu.addAction('新建模板')
            add_dir_action = menu.addAction('新建目录')
            
            action = menu.exec(self.tree.viewport().mapToGlobal(position))
            if action == add_template_action:
                self.add_template()
            elif action == add_dir_action:
                self.add_directory()
        elif item_type == 'directory':
            # 目录菜单
            add_template_action = menu.addAction('新建模板')
            add_dir_action = menu.addAction('新建目录')
            delete_action = menu.addAction('删除目录')
            
            action = menu.exec(self.tree.viewport().mapToGlobal(position))
            if action == add_template_action:
                self.add_template(item)
            elif action == add_dir_action:
                self.add_directory(item)
            elif action == delete_action:
                self.delete_directory(item)
        elif item_type == 'template':
            # 模板菜单
            edit_action = menu.addAction('编辑')
            delete_action = menu.addAction('删除')
            generate_action = menu.addAction('生成')
            
            action = menu.exec(self.tree.viewport().mapToGlobal(position))
            if action == edit_action:
                self.edit_template(item)
            elif action == delete_action:
                self.delete_template(item)
            elif action == generate_action:
                self.generate_template(item)

    def add_template(self, parent_item=None):
        """添加新模板"""
        # 确定模板保存路径
        if parent_item and parent_item != self.root:
            parent_data = parent_item.data(0, Qt.ItemDataRole.UserRole)
            if parent_data and parent_data['type'] == 'directory':
                template_dir = parent_data['path']
            else:
                template_dir = self.template_dir
        else:
            template_dir = self.template_dir
            
        # 直接打开编辑对话框
        dialog = TemplateEditDialog('', '', self)
        dialog.template_dir = template_dir  # 设置正确的模板目录
        dialog.setWindowTitle('新建模板')
        result = dialog.exec()
        
        if result == QDialog.DialogCode.Accepted:
            self.load_templates()  # 重新加载模板列表
    
    def add_directory(self, parent_item=None):
        """添加新目录"""
        name, ok = QInputDialog.getText(self, '新建目录', '请输入目录名称：')
        if ok and name:
            # 确定目录创建路径
            if parent_item and parent_item != self.root:
                parent_data = parent_item.data(0, Qt.ItemDataRole.UserRole)
                if parent_data and parent_data['type'] == 'directory':
                    parent_dir = parent_data['path']
                else:
                    parent_dir = self.template_dir
            else:
                parent_dir = self.template_dir
                
            # 创建新目录
            new_dir_path = os.path.join(parent_dir, name)
            if not os.path.exists(new_dir_path):
                os.makedirs(new_dir_path)
                self.load_templates()  # 重新加载模板列表
    
    def delete_directory(self, item):
        """删除目录"""
        if not item:
            return
            
        item_data = item.data(0, Qt.ItemDataRole.UserRole)
        if not item_data or item_data['type'] != 'directory':
            return
            
        dir_path = item_data['path']
        dir_name = item_data['name']
        
        # 确认是否删除
        from PySide6.QtWidgets import QMessageBox
        reply = QMessageBox.question(
            self,
            '确认删除',
            f'确定要删除目录 "{dir_name}" 及其所有内容吗？',
            QMessageBox.StandardButton.Yes | QMessageBox.StandardButton.No,
            QMessageBox.StandardButton.No
        )
        
        if reply == QMessageBox.StandardButton.Yes:
            import shutil
            try:
                shutil.rmtree(dir_path)
                self.load_templates()  # 重新加载模板列表
            except Exception as e:
                QMessageBox.critical(self, '删除失败', f'删除目录失败：{str(e)}')

    def edit_template(self, item):
        """编辑模板"""
        if not item:
            return
            
        item_data = item.data(0, Qt.ItemDataRole.UserRole)
        if not item_data or item_data['type'] != 'template':
            return
            
        template_path = item_data['path']
        template_name = item_data['name']
        
        # 获取模板所在目录
        template_dir = os.path.dirname(template_path)
        
        # 读取模板内容
        template_content = ''
        if os.path.exists(template_path):
            with open(template_path, 'r', encoding='utf-8') as f:
                template_content = f.read()
        
        # 打开编辑对话框
        dialog = TemplateEditDialog(template_name, template_content, self)
        dialog.template_dir = template_dir  # 设置正确的模板目录
        result = dialog.exec()
        
        if result == QDialog.DialogCode.Accepted:
            self.load_templates()  # 重新加载模板列表

    def delete_template(self, item):
        """删除模板"""
        if not item:
            return
            
        item_data = item.data(0, Qt.ItemDataRole.UserRole)
        if not item_data or item_data['type'] != 'template':
            return
            
        template_path = item_data['path']
        
        if os.path.exists(template_path):
            os.remove(template_path)
            self.load_templates()  # 重新加载模板列表

    def generate_template(self, item):
        """生成模板"""
        if not item:
            return
            
        item_data = item.data(0, Qt.ItemDataRole.UserRole)
        if not item_data or item_data['type'] != 'template':
            return
            
        template_path = item_data['path']
        template_name = item_data['name']
        
        # 读取模板内容
        template_content = ''
        if os.path.exists(template_path):
            with open(template_path, 'r', encoding='utf-8') as f:
                template_content = f.read()
        
        # 创建模板数据
        template_data = {
            'id': template_path,  # 使用文件路径作为唯一标识
            'name': template_name,
            'content': template_content
        }
        
        # 打开生成对话框
        dialog = TemplateGenerateDialog(template_data, self)
        dialog.exec()

    def handleDropEvent(self, event):
        """处理拖放事件，同步更新文件系统"""
        # 获取拖放的源项和目标项
        source_item = self.tree.currentItem()
        target_item = self.tree.itemAt(event.pos())
        
        # 如果没有源项或目标项，或者源项是根节点，则不处理
        if not source_item or not target_item or source_item == self.root:
            event.ignore()
            return
            
        # 获取源项和目标项的数据
        source_data = source_item.data(0, Qt.ItemDataRole.UserRole)
        target_data = target_item.data(0, Qt.ItemDataRole.UserRole)
        
        # 如果源项没有数据，则不处理
        if not source_data:
            event.ignore()
            return
            
        # 确定目标目录
        target_dir = None
        if target_item == self.root:
            target_dir = self.template_dir
        elif target_data and target_data['type'] == 'directory':
            target_dir = target_data['path']
        elif target_data and target_data['type'] == 'template':
            # 如果目标是模板文件，则使用其所在目录作为目标目录
            target_dir = os.path.dirname(target_data['path'])
        
        # 如果没有确定目标目录，则不处理
        if not target_dir:
            event.ignore()
            return
            
        # 处理不同类型的源项
        if source_data['type'] == 'directory':
            # 移动目录
            source_dir = source_data['path']
            dir_name = source_data['name']
            new_dir_path = os.path.join(target_dir, dir_name)
            
            # 检查是否是移动到自身或子目录
            if target_dir.startswith(source_dir):
                from PySide6.QtWidgets import QMessageBox
                QMessageBox.warning(self, '无法移动', '不能将目录移动到其自身或子目录中')
                event.ignore()
                return
                
            # 检查目标路径是否已存在同名目录
            if os.path.exists(new_dir_path):
                from PySide6.QtWidgets import QMessageBox
                QMessageBox.warning(self, '目录已存在', f'目标位置已存在名为 "{dir_name}" 的目录')
                event.ignore()
                return
                
            # 移动目录
            import shutil
            try:
                shutil.move(source_dir, new_dir_path)
                # 调用原始的dropEvent方法处理UI更新
                QTreeWidget.dropEvent(self.tree, event)
                # 重新加载模板列表以确保UI和文件系统同步
                self.load_templates()
            except Exception as e:
                from PySide6.QtWidgets import QMessageBox
                QMessageBox.critical(self, '移动失败', f'移动目录失败：{str(e)}')
                event.ignore()
                return
                
        elif source_data['type'] == 'template':
            # 移动模板文件
            source_path = source_data['path']
            template_name = source_data['name']
            new_template_path = os.path.join(target_dir, f'{template_name}.txt')
            
            # 检查目标路径是否已存在同名文件
            if os.path.exists(new_template_path):
                from PySide6.QtWidgets import QMessageBox
                QMessageBox.warning(self, '文件已存在', f'目标位置已存在名为 "{template_name}" 的模板')
                event.ignore()
                return
                
            # 移动文件
            import shutil
            try:
                shutil.move(source_path, new_template_path)
                # 调用原始的dropEvent方法处理UI更新
                QTreeWidget.dropEvent(self.tree, event)
                # 重新加载模板列表以确保UI和文件系统同步
                self.load_templates()
            except Exception as e:
                from PySide6.QtWidgets import QMessageBox
                QMessageBox.critical(self, '移动失败', f'移动模板失败：{str(e)}')
                event.ignore()
                return
        else:
            # 不支持的项类型
            event.ignore()
            return
    
    def filter_templates(self, text):
        """根据搜索文本过滤模板"""
        root = self.root
        self._filter_tree_items(root, text.lower())
        root.setExpanded(True)

    def _filter_tree_items(self, item, text):
        """递归过滤树形结构中的项目"""
        visible = False

        # 如果是模板节点，检查名称是否匹配
        item_data = item.data(0, Qt.ItemDataRole.UserRole)
        if item_data and item_data['type'] == 'template':
            visible = text == '' or text in item.text(0).lower()
            item.setHidden(not visible)
            return visible

        # 如果是目录节点，递归检查子节点
        for i in range(item.childCount()):
            child_visible = self._filter_tree_items(item.child(i), text)
            visible = visible or child_visible

        # 如果不是根节点，根据子节点的可见性决定是否显示
        if item != self.root:
            item.setHidden(not visible)

        return visible